package net.letcode.core.mvc.service.impl;

import net.letcode.core.mvc.bean.PageParams;
import net.letcode.core.mvc.dao.BaseDao;
import net.letcode.core.mvc.service.BaseService;
import net.letcode.core.utils.bean.IdEntity;
import net.letcode.core.utils.db.Page;
import net.letcode.core.utils.db.PageInfo;
import net.letcode.core.utils.db.Selector;

import java.lang.reflect.Field;
import java.util.List;

/**
 * 实现BaseService接口的抽象基类
 * @param <T>
 */
public abstract class BaseServiceImpl<T extends IdEntity> implements BaseService<T> {

    /** 实体DAO，将会在运行过程中动态从子类对象获取 */
    private BaseDao<T> baseDao;

    /**
     * 获取实体DAO，如果为空则从子类对象中动态获取
     * @return
     */
    private BaseDao<T> getDao(){
        if(baseDao == null){
            try {
                Field[] fields = this.getClass().getDeclaredFields();
                for (Field field : fields){
                    if(field.getAnnotation(net.letcode.core.mvc.annotation.BaseDao.class) != null){
                        field.setAccessible(true);
                        baseDao = (BaseDao<T>) field.get(this);
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            if(baseDao == null){
                System.out.println("获取实体DAO失败...");
            }
        }

        return baseDao;
    }

    @Override
    public T create(T entity) {
        getDao().insert(entity);
        return entity;
    }

    @Override
    public T update(T entity) {
        getDao().update(entity);
        return entity;
    }

    @Override
    public void updateStatus(Integer id, Integer status) {
        getDao().updateStatus(id, status);
    }

    @Override
    public void delete(Integer id) {
        getDao().deleteById(id);
    }

    @Override
    public void delete(String[] ids) {
        for (String id : ids) {
            delete(Integer.valueOf(id));
        }
    }

    @Override
    public T get(Integer id) {
        return getDao().selectOne(id);
    }

    @Override
    public Page<T> find(Selector selector, PageParams pageParams) {
        //构建查询参数
        String search = selector.hasContent() ? selector.toString() : null;
        String sort = pageParams.getSort();
        Integer pageNo = pageParams.getPage();
        Integer pageSize = pageParams.getSize();
        Integer offset = (pageNo - 1) * pageSize;

        sort = sort != null ? sort.replace("_", " ") : null;

        List<T> content = getDao().selectList(search, sort, offset, pageSize);
        Integer totalRows = getDao().count(search);
        Integer firstRow = (pageNo - 1) * pageSize;

        //封装查询结果
        Page<T> pageResult = new Page<T>();
        pageResult.setList(content);

        PageInfo pageInfo = new PageInfo();
        pageInfo.setPageNo(pageNo);
        pageInfo.setPageSize(pageSize);
        pageInfo.setSize(content.size());

        if(totalRows > 0)
            pageInfo.setFirst(firstRow + 1);
        else
            pageInfo.setFirst(0);

        pageInfo.setLast(firstRow + content.size());
        pageInfo.setRows(totalRows);

        if((totalRows % pageSize) == 0)
            pageInfo.setPageTotal((totalRows/pageSize));
        else
            pageInfo.setPageTotal((totalRows/pageSize + 1));

        pageResult.setInfo(pageInfo);

        return pageResult;
    }
}
